<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //1、函数的多面性 函数可以对代码进行封装 所以可以调用函数将代码运行起来，但是同时函数也是一个对象
        // function fn(){}
        // // fn对象下的name属性
        // console.log(fn.name)  
        // 1、call方法  该方法属于函数对象下的方法 
        // 语法：函数名称.call(对象,函数调用的额外参数)
        let obj = {};

        function fn(){
            // 当直接调用时 this表示的是window对象 所以 window.name = '嘉文'
            // 当执行 fn.call时  可以理解为将函数代码中所有的this全部换成了obj
            this.name = '嘉文';
            this.skill = 'eq';
            this.r = function(){
                console.log(this.name);
            }
        }
        // fn();
        // console.log(window)
        // 传递的第一个参数就是表示将函数中this换成谁
        // fn.call(obj)
        // console.log(obj)
        // obj.r();//还是指向到obj


        function func(name,skill){
            this.name = name;
            this.skill = skill;
        }
        // func.call 执行必定会将func函数调用起来 调用时 就需要给func传递额外的参数，这些额外的参数全部设置为call后面的参数
        func.call(obj,'贾克斯','反击风暴');
        console.log(obj)

        // 2、apply

        let obj2 = {};

        function fn2(name,skill){
            this.name = name;
            this.skill = skill;
        }
        // apply的使用与call一模一样 唯一的区别在于传递函数的额外参数需要包裹为一个数组
        fn2.apply(obj2,['痛苦之拥','制造寡妇']);
        console.log(obj2)

        // 3、bind 使用形式 函数名称.bind(对象) 不会将函数调用 返回的是一个新的函数
        let obj3 = {};

        function fn3(name,skill){
            this.name = name;
            this.skill = skill;
        }
        // fn3.bind(obj3) 返回的是一个修改this之后的函数
        fn3.bind(obj3)('影魔','aaaa')
        console.log(obj3)
    </script>
</body>
</html>